#include "msg_queue_interface.h"
#include "msg_queue_pid_define.h"
#include "function_interface.h"
#include "fpga_addr_define.h"
#include "utils.h"
#include <stdlib.h>
#include <time.h>
#include "debug.h"
#include <pthread.h>
#include <unistd.h>
#include <sys/syscall.h>
#include "misc.h"


typedef enum
{
    PULSE_OPERATE_UNBLOCK = 0,
    PULSE_OPERATE_BLOCK,
} pulseOperate_t;


/**
 * @brief 解封脉冲
 */
int PulseOperate_UnblockPulse(void)
{
    u16BitType_t cmd1;

    if(FuncInf_GetCmd(FUNCINF_CMD_IDX_1, &cmd1.u16Data) != FUNCINF_ERR_NONE)
    {
        PRINT_WARN("Get failure");
        return -1;
    }

    if(cmd1.bitData.b8 == 1)
    {
        cmd1.bitData.b8 = 0;
        if(FuncInf_SetCmd(FUNCINF_OPERATOR_PULSE_OPERATE, FUNCINF_CMD_IDX_1, cmd1.u16Data) != FUNCINF_ERR_NONE)
        {
            PRINT_WARN("Set failure");
            return -1;
        }
        PRINT_INFO("Pulse unblock");
    }

    return 0;
}


static int PulseOperate_GetOperate(pulseOperate_t *pOp)
{
    int16_t pacSet, qacSet, chrgPwrLmt, discPwrLmt;

    if(!pOp)
    {
        PRINT_WARN();
        return -1;
    }

    if(FuncInf_DirectReadFpga(FPGA_ADDR_APPOINT_TYPE_ACT_PWR, (uint16_t *)&pacSet) != FUNCINF_ERR_NONE)
    {
        PRINT_WARN("Get failure");
        return -2;
    }

    if(FuncInf_DirectReadFpga(FPGA_ADDR_APPOINT_TYPE_REACT_PWR, (uint16_t *)&qacSet) != FUNCINF_ERR_NONE)
    {
        PRINT_WARN("Get failure");
        return -2;
    }

    if(FuncInf_DirectReadFpga(FPGA_ADDR_LMT_TYPE_AC_PWR_CHRG, (uint16_t *)&chrgPwrLmt) != FUNCINF_ERR_NONE)
    {
        PRINT_WARN("Get failure");
        return -2;
    }

    if(FuncInf_DirectReadFpga(FPGA_ADDR_LMT_TYPE_AC_PWR_DISC, (uint16_t *)&discPwrLmt) != FUNCINF_ERR_NONE)
    {
        PRINT_WARN("Get failure");
        return -2;
    }

    if(qacSet == 0 && \
       (pacSet == 0 || \
       (pacSet > 0 && discPwrLmt == 0) || \
       (pacSet < 0 && chrgPwrLmt == 0)))
    {
        *pOp = PULSE_OPERATE_BLOCK;
    }
    else
    {
        *pOp = PULSE_OPERATE_UNBLOCK;
    }

    return 0;
}


static int PulseOperate_Handle(void)
{
    u16BitType_t cmd1;
    funcInfGridState_t gridState;
    pulseOperate_t op;

    if(FuncInf_GetGridState(NULL, &gridState) != 0)
    {
        PRINT_WARN("Get failure");
        return -1;
    }
    if(gridState != FUNCINF_GRID_STATE_ON)
    {
        PRINT_DEBUG("gridState[%d]", gridState);
        return 0;
    }

    if(FuncInf_GetCmd(FUNCINF_CMD_IDX_1, &cmd1.u16Data) != FUNCINF_ERR_NONE)
    {
        PRINT_WARN("Get failure");
        return -1;
    }

    if(PulseOperate_GetOperate(&op) != 0)
    {
        PRINT_WARN("Get failure");
        return -2;
    }

    if(op == PULSE_OPERATE_BLOCK)
    {
        if(cmd1.bitData.b8 == 0)
        {
            sleep(3);
            cmd1.bitData.b8 = 1;
            if(FuncInf_SetCmd(FUNCINF_OPERATOR_PULSE_OPERATE, FUNCINF_CMD_IDX_1, cmd1.u16Data) != FUNCINF_ERR_NONE)
            {
                PRINT_WARN("Set failure");
                return -1;
            }
            PRINT_INFO("Pulse block");
        }
    }
    else
    {
        if(cmd1.bitData.b8 == 1)
        {
            cmd1.bitData.b8 = 0;
            if(FuncInf_SetCmd(FUNCINF_OPERATOR_PULSE_OPERATE, FUNCINF_CMD_IDX_1, cmd1.u16Data) != FUNCINF_ERR_NONE)
            {
                PRINT_WARN("Set failure");
                return -1;
            }
            PRINT_INFO("Pulse unblock");
        }
    }

    return 0;
}


void PulseOperate_Thread(void *pPara)
{
    Misc_InitThread(__func__);

    int err, msgId, msgDataNum;
    char msgData[MSG_DATA_LEN] = {0};

    if((err = MsgQueue_Get(MSG_QUEUE_PID_PULSE_OPERATE, &msgId)) < 0)
	{
        // PRINT_ERROR("Get error[%d]", err);
		return;
	}

    MsgQueue_Send1(msgId, "1");

    while(1)
    {
        if((err = MsgQueue_Recv1(msgId, msgData)) < 0)
        {
            // PRINT_ERROR("Recv error[%d]", err);
        }

        msgDataNum = atoi(msgData);
        switch(msgDataNum)
        {
            case 1:
                PulseOperate_Handle(); 
                break;

            default:
                PRINT_WARN("error msgDataNum[%d]", msgDataNum);
                break;
        }
    }
}


/**
 * @brief 发送脉冲操作消息
 */
int PulseOperate_SendMessage(void)
{
    int err, msgId;

    if((err = MsgQueue_Get(MSG_QUEUE_PID_PULSE_OPERATE, &msgId)) < 0)
	{
        // PRINT_WARN("Get error[%d]", err);
		return -1;
	}

    if((err = MsgQueue_Send1(msgId, "1")) < 0)
    {
        PRINT_WARN("Send error[%d]", err);
        return -2;
    }

    return 0;
}
